home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 February (DVD) / PCWorld_2008-02_DVD.iso / v cisle / PHP / PHP.exe / xampp-win32-1.6.5-installer.exe / php / PEAR / Auth / RADIUS.php < prev    next >
Encoding:
PHP Script  |  2007-12-20  |  27.7 KB  |  990 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. /*
  4. Copyright (c) 2003, Michael Bretterklieber <michael@bretterklieber.com>
  5. All rights reserved.
  6.  
  7. Redistribution and use in source and binary forms, with or without 
  8. modification, are permitted provided that the following conditions 
  9. are met:
  10.  
  11. 1. Redistributions of source code must retain the above copyright 
  12.    notice, this list of conditions and the following disclaimer.
  13. 2. Redistributions in binary form must reproduce the above copyright 
  14.    notice, this list of conditions and the following disclaimer in the 
  15.    documentation and/or other materials provided with the distribution.
  16. 3. The names of the authors may not be used to endorse or promote products 
  17.    derived from this software without specific prior written permission.
  18.  
  19. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
  20. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
  21. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
  22. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
  23. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
  24. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
  25. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
  26. OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
  27. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
  28. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  
  30. This code cannot simply be copied and put under the GNU Public License or 
  31. any other GPL-like (LGPL, GPL2) License.
  32.  
  33.     $Id: RADIUS.php,v 1.7 2006/08/18 16:53:39 mbretter Exp $
  34. */
  35.  
  36. require_once 'PEAR.php';
  37.  
  38. /**
  39. * Client implementation of RADIUS. This are wrapper classes for
  40. * the RADIUS PECL. 
  41. * Provides RADIUS Authentication (RFC2865) and RADIUS Accounting (RFC2866).
  42. *
  43. * @package Auth_RADIUS
  44. * @author  Michael Bretterklieber <michael@bretterklieber.com>
  45. * @access  public
  46. * @version $Revision: 1.7 $
  47. */
  48.  
  49. PEAR::loadExtension('radius');
  50.  
  51. /**
  52.  * class Auth_RADIUS
  53.  *
  54.  * Abstract base class for RADIUS
  55.  *
  56.  * @package Auth_RADIUS 
  57.  */
  58. class Auth_RADIUS extends PEAR {
  59.  
  60.     /**
  61.      * List of RADIUS servers.
  62.      * @var  array
  63.      * @see  addServer(), putServer()
  64.      */
  65.     var $_servers  = array();
  66.     
  67.     /**
  68.      * Path to the configuration-file.
  69.      * @var  string
  70.      * @see  setConfigFile()
  71.      */
  72.     var $_configfile = null;
  73.     
  74.     /**
  75.      * Resource.
  76.      * @var  resource
  77.      * @see  open(), close()
  78.      */
  79.     var $res = null;
  80.     
  81.     /**
  82.      * Username for authentication and accounting requests.
  83.      * @var  string
  84.      */
  85.     var $username = null;
  86.  
  87.     /**
  88.      * Password for plaintext-authentication (PAP).
  89.      * @var  string
  90.      */
  91.     var $password = null;
  92.     
  93.     /**
  94.      * List of known attributes.
  95.      * @var  array
  96.      * @see  dumpAttributes(), getAttributes()
  97.      */
  98.     var $attributes = array();
  99.     
  100.     /**
  101.      * List of raw attributes.
  102.      * @var  array
  103.      * @see  dumpAttributes(), getAttributes()
  104.      */
  105.     var $rawAttributes = array();
  106.  
  107.     /**
  108.      * List of raw vendor specific attributes.
  109.      * @var  array
  110.      * @see  dumpAttributes(), getAttributes()
  111.      */
  112.     var $rawVendorAttributes = array();    
  113.     
  114.     /**
  115.      * Constructor
  116.      *
  117.      * Loads the RADIUS PECL/extension
  118.      *
  119.      * @return void
  120.      */
  121.     function Auth_RADIUS() 
  122.     {
  123.         $this->PEAR();
  124.     }
  125.     
  126.     /**
  127.      * Adds a RADIUS server to the list of servers for requests.
  128.      *
  129.      * At most 10 servers may be specified.    When multiple servers 
  130.      * are given, they are tried in round-robin fashion until a 
  131.      * valid response is received
  132.      *
  133.      * @access public
  134.      * @param  string  $servername   Servername or IP-Address
  135.      * @param  integer $port         Portnumber
  136.      * @param  string  $sharedSecret Shared secret
  137.      * @param  integer $timeout      Timeout for each request
  138.      * @param  integer $maxtries     Max. retries for each request          
  139.      * @return void
  140.      */
  141.     function addServer($servername = 'localhost', $port = 0, $sharedSecret = 'testing123', $timeout = 3, $maxtries = 3) 
  142.     {
  143.         $this->_servers[] = array($servername, $port, $sharedSecret, $timeout, $maxtries);    
  144.     }
  145.     
  146.     /**
  147.      * Returns an error message, if an error occurred.
  148.      *
  149.      * @access public
  150.      * @return string
  151.      */
  152.     function getError() 
  153.     {
  154.         return radius_strerror($this->res);
  155.     }
  156.     
  157.     /**
  158.      * Sets the configuration-file.
  159.      *
  160.      * @access public
  161.      * @param  string  $file Path to the configuration file    
  162.      * @return void
  163.      */    
  164.     function setConfigfile($file) 
  165.     {
  166.         $this->_configfile = $file;
  167.     }
  168.  
  169.     /**
  170.      * Puts an attribute.
  171.      *
  172.      * @access public
  173.      * @param  integer $attrib       Attribute-number
  174.      * @param  mixed   $port         Attribute-value
  175.      * @param  type    $type         Attribute-type
  176.      * @return bool  true on success, false on error
  177.      */    
  178.     function putAttribute($attrib, $value, $type = null) 
  179.     {
  180.         if ($type == null) {
  181.             $type = gettype($value);
  182.         }
  183.  
  184.         switch ($type) {
  185.         case 'integer':
  186.             return radius_put_int($this->res, $attrib, $value);
  187.         
  188.         case 'addr':
  189.             return radius_put_addr($this->res, $attrib, $value);
  190.             
  191.         case 'string':
  192.         default:
  193.             return radius_put_attr($this->res, $attrib, $value);
  194.         }
  195.  
  196.     }
  197.     
  198.     /**
  199.      * Puts a vendor-specific attribute.
  200.      *
  201.      * @access public
  202.      * @param  integer $vendor       Vendor (MSoft, Cisco, ...)
  203.      * @param  integer $attrib       Attribute-number
  204.      * @param  mixed   $port         Attribute-value
  205.      * @param  type    $type         Attribute-type
  206.      * @return bool  true on success, false on error
  207.      */ 
  208.     function putVendorAttribute($vendor, $attrib, $value, $type = null) 
  209.     {
  210.         
  211.         if ($type == null) {
  212.             $type = gettype($value);
  213.         }
  214.         
  215.         switch ($type) {
  216.         case 'integer':
  217.             return radius_put_vendor_int($this->res, $vendor, $attrib, $value);
  218.         
  219.         case 'addr':
  220.             return radius_put_vendor_addr($this->res, $vendor,$attrib, $value);
  221.             
  222.         case 'string':
  223.         default:
  224.             return radius_put_vendor_attr($this->res, $vendor, $attrib, $value);
  225.         }
  226.         
  227.     }    
  228.  
  229.     /**
  230.      * Prints known attributes received from the server.
  231.      *
  232.      * @access public
  233.      */     
  234.     function dumpAttributes()
  235.     {
  236.         foreach ($this->attributes as $name => $data) {
  237.             echo "$name:$data<br>\n";
  238.         }
  239.     }
  240.     
  241.     /**
  242.      * Overwrite this. 
  243.      *
  244.      * @access public
  245.      */         
  246.     function open() 
  247.     {
  248.     }
  249.  
  250.     /**
  251.      * Overwrite this.
  252.      *
  253.      * @access public
  254.      */         
  255.     function createRequest()
  256.     {
  257.     }
  258.     
  259.     /**
  260.      * Puts standard attributes.
  261.      *
  262.      * @access public
  263.      */ 
  264.     function putStandardAttributes()
  265.     {
  266.         if (isset($_SERVER)) {
  267.             $var = &$_SERVER;
  268.         } else {
  269.             $var = &$GLOBALS['HTTP_SERVER_VARS'];
  270.         }
  271.                 
  272.         $this->putAttribute(RADIUS_NAS_IDENTIFIER, isset($var['HTTP_HOST']) ? $var['HTTP_HOST'] : 'localhost');
  273.         $this->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_VIRTUAL);
  274.         $this->putAttribute(RADIUS_SERVICE_TYPE, RADIUS_FRAMED);
  275.         $this->putAttribute(RADIUS_FRAMED_PROTOCOL, RADIUS_PPP);
  276.         $this->putAttribute(RADIUS_CALLING_STATION_ID, isset($var['REMOTE_HOST']) ? $var['REMOTE_HOST'] : '127.0.0.1');
  277.     }
  278.     
  279.     /**
  280.      * Puts custom attributes.
  281.      *
  282.      * @access public
  283.      */ 
  284.     function putAuthAttributes()
  285.     {
  286.         if (isset($this->username)) {
  287.             $this->putAttribute(RADIUS_USER_NAME, $this->username);        
  288.         }
  289.     }
  290.     
  291.     /**
  292.      * Configures the radius library.
  293.      *
  294.      * @access public
  295.      * @param  string  $servername   Servername or IP-Address
  296.      * @param  integer $port         Portnumber
  297.      * @param  string  $sharedSecret Shared secret
  298.      * @param  integer $timeout      Timeout for each request
  299.      * @param  integer $maxtries     Max. retries for each request          
  300.      * @return bool  true on success, false on error
  301.      * @see addServer()
  302.      */      
  303.     function putServer($servername, $port = 0, $sharedsecret = 'testing123', $timeout = 3, $maxtries = 3) 
  304.     {
  305.         if (!radius_add_server($this->res, $servername, $port, $sharedsecret, $timeout, $maxtries)) {
  306.             return false;
  307.         }
  308.         return true;
  309.     }
  310.     
  311.     /**
  312.      * Configures the radius library via external configurationfile
  313.      *
  314.      * @access public
  315.      * @param  string  $servername   Servername or IP-Address
  316.      * @return bool  true on success, false on error
  317.      */      
  318.     function putConfigfile($file) 
  319.     {
  320.         if (!radius_config($this->res, $file)) {
  321.             return false;
  322.         }
  323.         return true;
  324.     }    
  325.         
  326.     /**
  327.      * Initiates a RADIUS request. 
  328.      *
  329.      * @access public
  330.      * @return bool  true on success, false on errors     
  331.      */ 
  332.     function start()
  333.     {
  334.         if (!$this->open()) {
  335.             return false;
  336.         }
  337.         
  338.         foreach ($this->_servers as $s) {
  339.             // Servername, port, sharedsecret, timeout, retries
  340.             if (!$this->putServer($s[0], $s[1], $s[2], $s[3], $s[4])) {
  341.                 return false;
  342.             }
  343.         }
  344.         
  345.         if (!empty($this->_configfile)) {
  346.             if (!$this->putConfigfile($this->_configfile)) {
  347.                 return false;
  348.             }
  349.         }
  350.         
  351.         $this->createRequest();
  352.         $this->putStandardAttributes();
  353.         $this->putAuthAttributes();
  354.         return true;
  355.     }
  356.     
  357.     /**
  358.      * Sends a prepared RADIUS request and waits for a response
  359.      *
  360.      * @access public
  361.      * @return mixed  true on success, false on reject, PEAR_Error on error
  362.      */ 
  363.     function send()
  364.     {
  365.         $req = radius_send_request($this->res);
  366.         if (!$req) {
  367.             return $this->raiseError('Error sending request: ' . $this->getError());
  368.         }
  369.  
  370.         switch($req) {
  371.         case RADIUS_ACCESS_ACCEPT:
  372.             if (is_subclass_of($this, 'auth_radius_acct')) {
  373.                 return $this->raiseError('RADIUS_ACCESS_ACCEPT is unexpected for accounting');
  374.             }
  375.             return true;
  376.  
  377.         case RADIUS_ACCESS_REJECT:
  378.             return false;
  379.             
  380.         case RADIUS_ACCOUNTING_RESPONSE:
  381.             if (is_subclass_of($this, 'auth_radius_pap')) {
  382.                 return $this->raiseError('RADIUS_ACCOUNTING_RESPONSE is unexpected for authentication');
  383.             }
  384.             return true;
  385.  
  386.         default:
  387.             return $this->raiseError("Unexpected return value: $req");
  388.         }    
  389.         
  390.     }
  391.  
  392.     /**
  393.      * Reads all received attributes after sending the request.
  394.      *
  395.      * This methos stores known attributes in the property attributes, 
  396.      * all attributes (including known attibutes) are stored in rawAttributes 
  397.      * or rawVendorAttributes.
  398.      * NOTE: call this function also even if the request was rejected, because the 
  399.      * Server returns usualy an errormessage
  400.      *
  401.      * @access public
  402.      * @return bool   true on success, false on error
  403.      */     
  404.     function getAttributes()
  405.     {
  406.  
  407.         while ($attrib = radius_get_attr($this->res)) {
  408.  
  409.             if (!is_array($attrib)) {
  410.                 return false;
  411.             }        
  412.  
  413.             $attr = $attrib['attr'];
  414.             $data = $attrib['data'];
  415.  
  416.             $this->rawAttributes[$attr] = $data;
  417.  
  418.             switch ($attr) {
  419.             case RADIUS_FRAMED_IP_ADDRESS:
  420.                 $this->attributes['framed_ip'] = radius_cvt_addr($data);
  421.                 break;
  422.  
  423.             case RADIUS_FRAMED_IP_NETMASK:
  424.                 $this->attributes['framed_mask'] = radius_cvt_addr($data);
  425.                 break;
  426.  
  427.             case RADIUS_FRAMED_MTU:
  428.                 $this->attributes['framed_mtu'] = radius_cvt_int($data);
  429.                 break;
  430.  
  431.             case RADIUS_FRAMED_COMPRESSION:
  432.                 $this->attributes['framed_compression'] = radius_cvt_int($data);
  433.                 break;
  434.  
  435.             case RADIUS_SESSION_TIMEOUT:
  436.                 $this->attributes['session_timeout'] = radius_cvt_int($data);
  437.                 break;
  438.  
  439.             case RADIUS_IDLE_TIMEOUT:
  440.                 $this->attributes['idle_timeout'] = radius_cvt_int($data);
  441.                 break;
  442.  
  443.             case RADIUS_SERVICE_TYPE:
  444.                 $this->attributes['service_type'] = radius_cvt_int($data);
  445.                 break;
  446.  
  447.             case RADIUS_CLASS:
  448.                 $this->attributes['class'] = radius_cvt_string($data);
  449.                 break;
  450.  
  451.             case RADIUS_FRAMED_PROTOCOL:
  452.                 $this->attributes['framed_protocol'] = radius_cvt_int($data);
  453.                 break;
  454.  
  455.             case RADIUS_FRAMED_ROUTING:
  456.                 $this->attributes['framed_routing'] = radius_cvt_int($data);
  457.                 break;
  458.  
  459.             case RADIUS_FILTER_ID:
  460.                 $this->attributes['filter_id'] = radius_cvt_string($data);
  461.                 break;
  462.  
  463.             case RADIUS_REPLY_MESSAGE:
  464.                 $this->attributes['reply_message'] = radius_cvt_string($data);
  465.                 break;
  466.  
  467.             case RADIUS_VENDOR_SPECIFIC:
  468.                 $attribv = radius_get_vendor_attr($data);
  469.                 if (!is_array($attribv)) {
  470.                     return false;
  471.                 }
  472.                     
  473.                 $vendor = $attribv['vendor'];
  474.                 $attrv = $attribv['attr'];
  475.                 $datav = $attribv['data'];
  476.                 
  477.                 $this->rawVendorAttributes[$vendor][$attrv] = $datav;
  478.  
  479.                 if ($vendor == RADIUS_VENDOR_MICROSOFT) {
  480.  
  481.                     switch ($attrv) {
  482.                     case RADIUS_MICROSOFT_MS_CHAP2_SUCCESS:
  483.                         $this->attributes['ms_chap2_success'] = radius_cvt_string($datav);
  484.                         break;
  485.  
  486.                     case RADIUS_MICROSOFT_MS_CHAP_ERROR:
  487.                         $this->attributes['ms_chap_error'] = radius_cvt_string(substr($datav,1));
  488.                         break;
  489.  
  490.                     case RADIUS_MICROSOFT_MS_CHAP_DOMAIN:
  491.                         $this->attributes['ms_chap_domain'] = radius_cvt_string($datav);
  492.                         break;
  493.  
  494.                     case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY:
  495.                         $this->attributes['ms_mppe_encryption_policy'] = radius_cvt_int($datav);
  496.                         break;
  497.  
  498.                     case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES:
  499.                         $this->attributes['ms_mppe_encryption_types'] = radius_cvt_int($datav);
  500.                         break;
  501.  
  502.                     case RADIUS_MICROSOFT_MS_CHAP_MPPE_KEYS:
  503.                         $demangled = radius_demangle($this->res, $datav);
  504.                         $this->attributes['ms_chap_mppe_lm_key'] = substr($demangled, 0, 8);
  505.                         $this->attributes['ms_chap_mppe_nt_key'] = substr($demangled, 8, RADIUS_MPPE_KEY_LEN);
  506.                         break;
  507.  
  508.                     case RADIUS_MICROSOFT_MS_MPPE_SEND_KEY:
  509.                         $this->attributes['ms_chap_mppe_send_key'] = radius_demangle_mppe_key($this->res, $datav);
  510.                         break;
  511.  
  512.                     case RADIUS_MICROSOFT_MS_MPPE_RECV_KEY:
  513.                         $this->attributes['ms_chap_mppe_recv_key'] = radius_demangle_mppe_key($this->res, $datav);
  514.                         break;
  515.  
  516.                     case RADIUS_MICROSOFT_MS_PRIMARY_DNS_SERVER:
  517.                         $this->attributes['ms_primary_dns_server'] = radius_cvt_string($datav);
  518.                         break;
  519.                     }
  520.                 }
  521.                 break;
  522.                 
  523.             }
  524.         }    
  525.  
  526.         return true;
  527.     }
  528.     
  529.     /**
  530.      * Frees resources.
  531.      *
  532.      * Calling this method is always a good idea, because all security relevant
  533.      * attributes are filled with Nullbytes to leave nothing in the mem.
  534.      *
  535.      * @access public
  536.      */   
  537.     function close()
  538.     {
  539.         if ($this->res != null) {
  540.             radius_close($this->res);
  541.             $this->res = null;
  542.         }
  543.         $this->username = str_repeat("\0", strlen($this->username));
  544.         $this->password = str_repeat("\0", strlen($this->password));
  545.     }
  546.     
  547. }
  548.  
  549. /**
  550.  * class Auth_RADIUS_PAP
  551.  *
  552.  * Class for authenticating using PAP (Plaintext)
  553.  * 
  554.  * @package Auth_RADIUS 
  555.  */
  556. class Auth_RADIUS_PAP extends Auth_RADIUS 
  557. {
  558.  
  559.     /**
  560.      * Constructor
  561.      *
  562.      * @param  string  $username   Username
  563.      * @param  string  $password   Password
  564.      * @return void
  565.      */
  566.     function Auth_RADIUS_PAP($username = null, $password = null)
  567.     {
  568.         $this->Auth_RADIUS();
  569.         $this->username = $username;
  570.         $this->password = $password;
  571.     }
  572.     
  573.     /**
  574.      * Creates a RADIUS resource
  575.      *
  576.      * Creates a RADIUS resource for authentication. This should be the first
  577.      * call before you make any other things with the library.
  578.      *
  579.      * @return bool   true on success, false on error
  580.      */
  581.     function open() 
  582.     {
  583.         $this->res = radius_auth_open();
  584.         if (!$this->res) {
  585.             return false;
  586.         }
  587.         return true;
  588.     }
  589.     
  590.     /**
  591.      * Creates an authentication request 
  592.      *
  593.      * Creates an authentication request.
  594.      * You MUST call this method before you can put any attribute
  595.      *
  596.      * @return bool   true on success, false on error
  597.      */
  598.     function createRequest()
  599.     {
  600.         if (!radius_create_request($this->res, RADIUS_ACCESS_REQUEST)) {
  601.             return false;
  602.         }
  603.         return true;
  604.     }
  605.  
  606.     /**
  607.      * Put authentication specific attributes 
  608.      *
  609.      * @return void
  610.      */
  611.     function putAuthAttributes()
  612.     {
  613.         if (isset($this->username)) {
  614.             $this->putAttribute(RADIUS_USER_NAME, $this->username);        
  615.         }
  616.         if (isset($this->password)) {
  617.             $this->putAttribute(RADIUS_USER_PASSWORD, $this->password);
  618.         }
  619.     }
  620.  
  621. }
  622.  
  623. /**
  624.  * class Auth_RADIUS_CHAP_MD5
  625.  *
  626.  * Class for authenticating using CHAP-MD5 see RFC1994.
  627.  * Instead og the plaintext password the challenge and 
  628.  * the response are needed.
  629.  * 
  630.  * @package Auth_RADIUS 
  631.  */
  632. class Auth_RADIUS_CHAP_MD5 extends Auth_RADIUS_PAP
  633. {
  634.     /**
  635.      * 8 Bytes binary challenge
  636.      * @var  string
  637.      */
  638.     var $challenge = null;
  639.  
  640.     /**
  641.      * 16 Bytes MD5 response binary
  642.      * @var  string
  643.      */
  644.     var $response = null;
  645.     
  646.     /**
  647.      * Id of the authentication request. Should incremented after every request.
  648.      * @var  integer
  649.      */
  650.     var $chapid = 1;
  651.     
  652.     /**
  653.      * Constructor
  654.      *
  655.      * @param  string  $username   Username
  656.      * @param  string  $challenge  8 Bytes Challenge (binary)
  657.      * @param  integer $chapid     Requestnumber
  658.      * @return void
  659.      */
  660.     function Auth_RADIUS_CHAP_MD5($username = null, $challenge = null, $chapid = 1)
  661.     {
  662.         $this->Auth_RADIUS_PAP();
  663.         $this->username = $username;
  664.         $this->challenge = $challenge;
  665.         $this->chapid = $chapid;
  666.     }
  667.     
  668.     /**
  669.      * Put CHAP-MD5 specific attributes
  670.      *
  671.      * For authenticating using CHAP-MD5 via RADIUS you have to put the challenge 
  672.      * and the response. The chapid is inserted in the first byte of the response.
  673.      *
  674.      * @return void
  675.      */
  676.     function putAuthAttributes()
  677.     {
  678.         if (isset($this->username)) {
  679.             $this->putAttribute(RADIUS_USER_NAME, $this->username);        
  680.         }
  681.         if (isset($this->response)) {
  682.             $response = pack('C', $this->chapid) . $this->response;
  683.             $this->putAttribute(RADIUS_CHAP_PASSWORD, $response);
  684.         }
  685.         if (isset($this->challenge)) {
  686.             $this->putAttribute(RADIUS_CHAP_CHALLENGE, $this->challenge);
  687.         }
  688.     }
  689.     
  690.     /**
  691.      * Frees resources.
  692.      *
  693.      * Calling this method is always a good idea, because all security relevant
  694.      * attributes are filled with Nullbytes to leave nothing in the mem.
  695.      *
  696.      * @access public
  697.      */   
  698.     function close()
  699.     {
  700.         Auth_RADIUS_PAP::close();
  701.         $this->challenge =  str_repeat("\0", strlen($this->challenge));
  702.         $this->response =  str_repeat("\0", strlen($this->response));
  703.     }    
  704.     
  705. }
  706.  
  707. /**
  708.  * class Auth_RADIUS_MSCHAPv1
  709.  *
  710.  * Class for authenticating using MS-CHAPv1 see RFC2433
  711.  * 
  712.  * @package Auth_RADIUS 
  713.  */
  714. class Auth_RADIUS_MSCHAPv1 extends Auth_RADIUS_CHAP_MD5 
  715. {
  716.     /**
  717.      * LAN-Manager-Response
  718.      * @var  string
  719.      */
  720.     var $lmResponse = null;
  721.  
  722.     /**
  723.      * Wether using deprecated LM-Responses or not.
  724.      * 0 = use LM-Response, 1 = use NT-Response
  725.      * @var  bool
  726.      */
  727.     var $flags = 1;
  728.     
  729.     /**
  730.      * Put MS-CHAPv1 specific attributes 
  731.      *
  732.      * For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge 
  733.      * and the response. The response has this structure:
  734.      * struct rad_mschapvalue {
  735.      *   u_char ident;
  736.      *   u_char flags;
  737.      *   u_char lm_response[24];
  738.      *   u_char response[24];
  739.      * };
  740.      * 
  741.      * @return void
  742.      */
  743.     function putAuthAttributes()
  744.     {
  745.         if (isset($this->username)) {
  746.             $this->putAttribute(RADIUS_USER_NAME, $this->username);        
  747.         }
  748.         if (isset($this->response) || isset($this->lmResponse)) {
  749.             $lmResp = isset($this->lmResponse) ? $this->lmResponse : str_repeat ("\0", 24);
  750.             $ntResp = isset($this->response)   ? $this->response :   str_repeat ("\0", 24);
  751.             $resp = pack('CC', $this->chapid, $this->flags) . $lmResp . $ntResp;
  752.             $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_RESPONSE, $resp);
  753.         }
  754.         if (isset($this->challenge)) {        
  755.             $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
  756.         }
  757.     }    
  758. }
  759.  
  760. /**
  761.  * class Auth_RADIUS_MSCHAPv2
  762.  *
  763.  * Class for authenticating using MS-CHAPv2 see RFC2759
  764.  * 
  765.  * @package Auth_RADIUS 
  766.  */
  767. class Auth_RADIUS_MSCHAPv2 extends Auth_RADIUS_MSCHAPv1 
  768. {
  769.     /**
  770.      * 16 Bytes binary challenge
  771.      * @var  string
  772.      */
  773.     var $challenge = null;
  774.     
  775.     /**
  776.      * 16 Bytes binary Peer Challenge
  777.      * @var  string
  778.      */
  779.     var $peerChallenge = null;
  780.  
  781.   /**
  782.      * Put MS-CHAPv2 specific attributes 
  783.      *
  784.      * For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge 
  785.      * and the response. The response has this structure:
  786.      * struct rad_mschapv2value {
  787.      *   u_char ident;
  788.      *   u_char flags;
  789.      *   u_char pchallenge[16];
  790.      *   u_char reserved[8];
  791.      *   u_char response[24];
  792.      * };
  793.      * where pchallenge is the peer challenge. Like for MS-CHAPv1 we set the flags field to 1.
  794.      * @return void
  795.      */    
  796.     function putAuthAttributes()
  797.     {
  798.         if (isset($this->username)) {
  799.             $this->putAttribute(RADIUS_USER_NAME, $this->username);        
  800.         }
  801.         if (isset($this->response) && isset($this->peerChallenge)) {
  802.             // Response: chapid, flags (1 = use NT Response), Peer challenge, reserved, Response        
  803.             $resp = pack('CCa16a8a24',$this->chapid , 1, $this->peerChallenge, str_repeat("\0", 8), $this->response);        
  804.             $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP2_RESPONSE, $resp);
  805.         }
  806.         if (isset($this->challenge)) {
  807.             $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
  808.         }
  809.     }    
  810.     
  811.     /**
  812.      * Frees resources.
  813.      *
  814.      * Calling this method is always a good idea, because all security relevant
  815.      * attributes are filled with Nullbytes to leave nothing in the mem.
  816.      *
  817.      * @access public
  818.      */   
  819.     function close()
  820.     {
  821.         Auth_RADIUS_MSCHAPv1::close();
  822.         $this->peerChallenge = str_repeat("\0", strlen($this->peerChallenge));
  823.     }       
  824. }
  825.  
  826. /**
  827.  * class Auth_RADIUS_Acct
  828.  *
  829.  * Class for RADIUS accounting
  830.  * 
  831.  * @package Auth_RADIUS 
  832.  */
  833. class Auth_RADIUS_Acct extends Auth_RADIUS 
  834. {
  835.     /**
  836.      * Defines where the Authentication was made, possible values are:
  837.      * RADIUS_AUTH_RADIUS, RADIUS_AUTH_LOCAL, RADIUS_AUTH_REMOTE
  838.      * @var  integer
  839.      */
  840.     var $authentic = null;
  841.  
  842.    /**
  843.      * Defines the type of the accounting request, on of:
  844.      * RADIUS_START, RADIUS_STOP, RADIUS_ACCOUNTING_ON, RADIUS_ACCOUNTING_OFF
  845.      * @var  integer
  846.      */    
  847.     var $status_type = null;
  848.  
  849.    /**
  850.      * The time the user was logged in in seconds
  851.      * @var  integer
  852.      */    
  853.     var $session_time = null;
  854.  
  855.    /**
  856.      * A uniq identifier for the session of the user, maybe the PHP-Session-Id
  857.      * @var  string
  858.      */    
  859.     var $session_id = null;
  860.     
  861.     /**
  862.      * Constructor
  863.      *
  864.      * Generates a predefined session_id. We use the Remote-Address, the PID, and the Current user.
  865.      * @return void
  866.      */
  867.     function Auth_RADIUS_Acct()
  868.     {
  869.         $this->Auth_RADIUS();
  870.         
  871.         if (isset($_SERVER)) {
  872.             $var = &$_SERVER;
  873.         } else {
  874.             $var = &$GLOBALS['HTTP_SERVER_VARS'];
  875.         }
  876.  
  877.         $this->session_id = sprintf("%s:%d-%s", isset($var['REMOTE_ADDR']) ? $var['REMOTE_ADDR'] : '127.0.0.1' , getmypid(), get_current_user());
  878.     }
  879.  
  880.     /**
  881.      * Creates a RADIUS resource
  882.      *
  883.      * Creates a RADIUS resource for accounting. This should be the first
  884.      * call before you make any other things with the library.
  885.      *
  886.      * @return bool   true on success, false on error
  887.      */
  888.     function open() 
  889.     {
  890.         $this->res = radius_acct_open();
  891.         if (!$this->res) {
  892.             return false;
  893.         }
  894.         return true;
  895.     }
  896.  
  897.    /**
  898.      * Creates an accounting request 
  899.      *
  900.      * Creates an accounting request.
  901.      * You MUST call this method before you can put any attribute.
  902.      *
  903.      * @return bool   true on success, false on error
  904.      */
  905.     function createRequest()
  906.     {
  907.         if (!radius_create_request($this->res, RADIUS_ACCOUNTING_REQUEST)) {
  908.             return false;
  909.         }
  910.         return true;
  911.     }   
  912.    
  913.   /**
  914.      * Put attributes for accounting.
  915.      *
  916.      * Here we put some accounting values. There many more attributes for accounting, 
  917.      * but for web-applications only certain attributes make sense.
  918.      * @return void
  919.      */ 
  920.     function putAuthAttributes()
  921.     {
  922.         $this->putAttribute(RADIUS_ACCT_SESSION_ID, $this->session_id);
  923.         $this->putAttribute(RADIUS_ACCT_STATUS_TYPE, $this->status_type);
  924.         if (isset($this->session_time) && $this->status_type == RADIUS_STOP) {
  925.             $this->putAttribute(RADIUS_ACCT_SESSION_TIME, $this->session_time);
  926.         }
  927.         if (isset($this->authentic)) {
  928.             $this->putAttribute(RADIUS_ACCT_AUTHENTIC, $this->authentic);
  929.         }
  930.         
  931.     }    
  932.     
  933. }
  934.  
  935. /**
  936.  * class Auth_RADIUS_Acct_Start
  937.  *
  938.  * Class for RADIUS accounting. Its usualy used, after the user has logged in.
  939.  * 
  940.  * @package Auth_RADIUS
  941.  */
  942. class Auth_RADIUS_Acct_Start extends Auth_RADIUS_Acct 
  943. {
  944.    /**
  945.      * Defines the type of the accounting request.
  946.      * It is set to RADIUS_START by default in this class.
  947.      * @var  integer
  948.      */    
  949.     var $status_type = RADIUS_START;
  950. }
  951.  
  952. /**
  953.  * class Auth_RADIUS_Acct_Start
  954.  *
  955.  * Class for RADIUS accounting. Its usualy used, after the user has logged out.
  956.  *
  957.  * @package Auth_RADIUS
  958.  */
  959. class Auth_RADIUS_Acct_Stop extends Auth_RADIUS_Acct
  960. {
  961.    /**
  962.      * Defines the type of the accounting request.
  963.      * It is set to RADIUS_STOP by default in this class.
  964.      * @var  integer
  965.      */
  966.     var $status_type = RADIUS_STOP;
  967. }
  968.  
  969. if (!defined('RADIUS_UPDATE'))
  970.     define('RADIUS_UPDATE', 3);
  971.  
  972. /**
  973.  * class Auth_RADIUS_Acct_Update
  974.  *
  975.  * Class for interim RADIUS accounting updates.
  976.  *
  977.  * @package Auth_RADIUS
  978.  */
  979. class Auth_RADIUS_Acct_Update extends Auth_RADIUS_Acct
  980. {
  981.    /**
  982.      * Defines the type of the accounting request.
  983.      * It is set to RADIUS_UPDATE by default in this class.
  984.      * @var  integer
  985.      */
  986.     var $status_type = RADIUS_UPDATE;
  987. }
  988.  
  989. ?>
  990.